# !/usr/bin/env python
# encoding: utf-8


"""
  @author: gaogao
  @file: Mux_Heater_IV.py
  @time: 2022/5/11 9:35
  @desc:
"""

import time

from math import *
from ATS.hardwarescan import conf_file_manager
from ATS.application.LCR_App.U2722A_App import U2722A_App
from ATS.application.LASER_App.L8164B_App import L8164B_App
from ATS.application.LASER_App.N7744C_App import N7744C_App
from ATS.datamanager import data_transfer_station as DataTransferStation
from ATS.application.VNA_App.N5225B_App import N5225BApp
from ATS.util.calcu_step_util import get_points_list
from ATS.util.save_data_2_csv_util import saveData2CSV
from matplotlib import pyplot as plt
from ATS.switchdriver.LightSwitchDriver import LightSwitchDriver
import numpy as np
from utils.find3db_util import find3db_util
from utils.find_first_minimum_util import find_first_minimaxmum
from utils.save_setting_2_ini import save_ini_info
from gui import constant
from collections import namedtuple
from utils.read_ini_2_dict import get_option_value


# def Mux_Heater_IV(pre_sweep_channel=3, start_voltage=0, stop_voltage=2.5, points=101, sweep_channel=1,
#                   sweep_channel_range="120mA",
#                   sweep_channel_limit=0.12,
#                   bias_channel=1, bias_channel_voltage=-2, bias_channel_current_range="100uA",
#                   bias_channel_limit=0.0001):
def Mux_Heater_IV(para):
    print("para", para)
    result_data = namedtuple("result_data", "subdie,test_item,test_result")

    l8164b_app = L8164B_App("SS3")
    l8164b_app.set_power_unit()
    l8164b_app.set_power_value(para.l8164_setting["power_value"])
    l8164b_app.set_wave_length(para.l8164_setting["wave_length"][0])

    l8164b_app.output_on()

    smu_setting = para.smu_setting
    print("smu_setting", smu_setting)
    smu_dict = {}

    # smu voltage_list channel nplc current_range current_limit //mode sweep
    #
    mes_plans_dict = {"var_func": None, "var1": None, "measure_func": None}
    init_set_list = []
    for smu in smu_setting:
        if smu["smu"] not in smu_dict:
            smu_dict[smu["smu"]] = U2722A_App(smu["smu"])
        current_inst = smu_dict[smu["smu"]]
        current_voltage_list = smu["voltage_list"]
        current_channel = smu["channel"]
        current_channel_nplc = smu["nplc"]
        current_channel_range = smu["current_range"]
        current_channel_limit = smu["current_limit"]
        init_set_list += [lambda x=current_channel, inst_obj=current_inst: inst_obj.set_voltage_range(x),
                          lambda x=current_channel_nplc, y=current_channel,
                                 inst_obj=current_inst: inst_obj.set_current_nplc(x, y),
                          lambda x=current_channel_range, y=current_channel_limit,
                                 z=current_channel, inst_obj=current_inst: inst_obj.set_current_range_limit(x, y,
                                                                                                            z)]
        if smu["mode"] == "sweep":
            mes_plans_dict["var1"] = current_voltage_list
            mes_plans_dict["var_func"] = lambda volt, x=current_channel, inst_obj=current_inst: \
                inst_obj.set_voltage(volt, x)
        else:
            init_set_list += [lambda volt=current_voltage_list[0], x=current_channel, inst_obj=current_inst: \
                                  inst_obj.set_voltage(volt, x)]

        if smu["is_measure"]:
            mes_plans_dict["measure_func"] = lambda x=current_inst: abs(
                float(current_inst.get_current_value(current_channel)))

    # set init
    for inst_set_func in init_set_list:
        inst_set_func()  # 设置SMU

    # read mes
    current_list = []  # result list
    mes_func = mes_plans_dict["measure_func"]
    if mes_func:  # mes func不为空
        if mes_plans_dict["var1"]:  # sweep
            for volt in mes_plans_dict["var1"]:
                print("volt", volt)
                mes_plans_dict["var_func"](volt)
                current_list.append(mes_func())
        else:
            current_list.append(mes_func())  # spot

    print("current_list", current_list)
    voltage_list = [float(i) for i in mes_plans_dict["var1"]]

    vh = eval(get_option_value(option="vh"))
    print("vh", vh)
    # voltage_list = get_points_list(start_voltage, stop_voltage, points)
    voltage_list = [float(i) for i in voltage_list]
    print("voltage_list", voltage_list)
    # sweep_inst.set_voltage_range(2)
    # sweep_inst.set_current_range_limit(sweep_channel_range, sweep_channel_limit, 2)
    # sweep_inst.set_voltage(vh[0], 2)

    if all([voltage_list, current_list]):
        # plot_curve1(voltage_list, current_list)
        DataTransferStation.get_DTS().postarraydata("test", result_data(para.subdie, para.test_item,
                                                                        (voltage_list, current_list)))
        vh = find_first_minimaxmum(voltage_list, current_list)
        print("vh", vh)
        save_ini_info(constant.REMEMBER_VALUE, "remember_value", "vh1", str(vh))

        return voltage_list, current_list


def plot_curve1(x_data, y_data):
    plt.plot(x_data, y_data, "b")
    plt.xlabel("Voltage")
    plt.ylabel("Current")
    plt.grid(True)
    plt.show()


Mux_Heater_IV(locals()["para"])


# # p_拉姆达
                    # wave_list = get_step_list(1260, 1360, 1)
                    # n7744c_app.set_logging_state("STOP")
                    # points = len(wave_list)
                    # l8164b_app.set_power_unit()
                    # l8164b_app.set_power_value(para.l8164_setting["power_value"])
                    # time.sleep(4)
                    # p_in = l8164b_app.fetch_input_power()
                    # time.sleep(2)
                    # l8164b_app.set_sweep_mode()
                    # l8164b_app.query_sweep_pmax(1260, 1360)
                    # l8164b_app.set_repeat_mode()
                    # l8164b_app.set_wave_sweep_speed(10)
                    # l8164b_app.set_start_stop_step_wave(1260, 1360, 1)
                    # l8164b_app.trigger_config()
                    # l8164b_app.trigger_output()
                    # l8164b_app.trigger_input()
                    # l8164b_app.output_on()
                    # l8164b_app.set_wave_sweep_state()
                    # time.sleep(2)
                    # # n7744c_app.reset()
                    # n7744c_app.set_power_unit()
                    # n7744c_app.set_power_range(para.n7744_setting["power_range"])
                    # n7744c_app.set_auto_gain()
                    # n7744c_app.set_power_atim(para.n7744_setting["atim"])
                    # n7744c_app.trigger_input_mode()
                    # n7744c_app.set_power_wave_length()
                    # n7744c_app.set_logging_points(points)
                    # n7744c_app.set_logging_state()
                    # n7744c_app.tigger_status()
                    # while True:
                    #     state = n7744c_app.get_func_state()
                    #     if state == "LOGGING_STABILITY,COMPLETE":
                    #         power_list = n7744c_app.get_func_res()
                    #         break
                    # power_list = [float(i) for i in power_list]
                    
                    # l8164b_app.stop_sweep()
                    # n7744c_app.set_logging_state("STOP")
                    # wave_power_tuple = get_refrence_data()
                    # measurement_parameter = f"{para.subdie}_{para.test_item}_{wave_length}_pλ"
                    # measurement_data = str([wave_list, power_list])
                    # data_unit = ""
                    # data_type = "Curve"
                    # Chip(chip_name, wafer_name, shot_position, shot_number, chip_number, polarization_type,
                    #      measurement_parameter, measurement_data,
                    #      data_unit, data_type).add()
                    # loss_section = f"{VarManager().diex}-{VarManager().diey}-{VarManager().subdie_name.split('_')[0]}_GC"
                    # print("pi",p_in)
                    # print("power_list",power_list)
                    # for wave_index in range(len(wave_list)):
                    #     loss_sys = get_wave_power_value(wave_list[wave_index], wave_power_tuple)
                    #     loss_gc = get_wave_loss_gc(wave_list[wave_index], get_loss_data(section=loss_section))
                    #     print("power_list[wave_index]",power_list[wave_index])
                    #     print("loss_sys",loss_sys)
                    #     print("loss_gc",loss_gc)
                        
                    #     power_list[wave_index] = float(p_in) \
                    #                          - power_list[wave_index] \
                    #                          - loss_sys \
                    #                          - 2 * loss_gc \
                    #                          - float(para.loss_coupler)

                    # print("x", wave_list)
                    # print("y", power_list)
                    # loss_section = f"{VarManager().diex}-{VarManager().diey}-{VarManager().subdie_name}_{wave_length}_pλ"
                    # curve_title = f"{VarManager().diex}-{VarManager().diey}-{VarManager().subdie_number}-{VarManager().subdie_name}-{para.subdie}_{para.test_item}_{wave_length}_pλ"
                    # x_label = "WaveLength"
                    # y_label = "Power"

                    # DataTransferStation.get_DTS().postarraydata("test",
                    #                                             result_data(loss_section, para.test_item, "line", True,
                    #                                                         curve_title, x_label, y_label,
                    #                                                         (wave_list, power_list)))
                    # print("qqqq")
                    # for wave in wave_list:
                    #     if float(wave) == float(para.l8164_setting["wave_length"][0]):
                    #         mux_il = power_list[wave_list.index(wave)]
                    #         measurement_parameter = f"{para.subdie}_{para.test_item}_{wave_length}_IL"
                    #         measurement_data = str(mux_il)
                    #         data_unit = "dB"
                    #         data_type = "Spot"
                    #         Chip(chip_name, wafer_name, shot_position, shot_number, chip_number, polarization_type,
                    #              measurement_parameter, measurement_data,
                    #              data_unit, data_type).add()
                    #         save_ini_info(constant.REMEMBER_VALUE, "remember_value",
                    #                       f"{title_section}_{wave_length}_IL", str(mux_il))
                    #         save_spot_data_2_file(f"{title_path}.csv", f"{title_section}_{wave_length}_IL", str(mux_il))
                    #         break